package com.example.opengldemo._camera_demo.provider;

import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.util.Log;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Semaphore;

public class CameraProvider implements ITextureProvider{

    private Camera mCamera;
    private int cameraId=0;
    private int minWidth = 720;
    private float rate = 1.67f;
    private Semaphore mFrameSem;
    private SurfaceTexture.OnFrameAvailableListener frameListener=new SurfaceTexture.OnFrameAvailableListener() {

        @Override
        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
            Log.e("CameraProvider" , "OnFrameAvailableListener 1 "+mFrameSem.availablePermits()) ;
            mFrameSem.drainPermits();
            mFrameSem.release();
            Log.e("CameraProvider" , "OnFrameAvailableListener 2 "+mFrameSem.availablePermits()) ;
        }

    };
    @Override
    public Point open(SurfaceTexture surface) {
        Log.e("CameraProvider" , "open") ;
        final Point size=new Point();
        try {
            mFrameSem=new Semaphore(0);
            mCamera=Camera.open(cameraId);
            onCameraOpened(mCamera);
            mCamera.setPreviewTexture(surface);
            surface.setOnFrameAvailableListener(frameListener);
            Camera.Size s=mCamera.getParameters().getPreviewSize();
            mCamera.startPreview();
            size.x=s.height;
            size.y=s.width;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return size;
    }

    public void setDefaultCamera(int id){
        cameraId = id;
    }
    public void setCameraSize(int minWidth,float rate){
        this.minWidth = minWidth;
        this.rate = rate;
    }

    protected void onCameraOpened(Camera camera){
        //小米5、5s这类奇葩手机不调用setParameters这句会导致图像预览方向错误
        Camera.Parameters param = camera.getParameters();
        List<Camera.Size> sizes = param.getSupportedPreviewSizes();
        Collections.sort(sizes, new Comparator<Camera.Size>() {
            @Override
            public int compare(android.hardware.Camera.Size o1, android.hardware.Camera.Size o2) {
                return o1.width - o2.width;
            }
        });
        for (android.hardware.Camera.Size s : sizes) {
            if (s.width >= minWidth) {
                if (rate > 1.4) {
                    if (s.width / (float) s.height > 1.4) {
                        param.setPreviewSize(s.width, s.height);
                        param.set("video-size", s.width + "x" + s.height);
                        break;
                    }
                } else {
                    if (s.width / (float) s.height < 1.4) {
                        param.setPreviewSize(s.width, s.height);
                        param.set("video-size", s.width + "x" + s.height);
                        break;
                    }
                }
            }
        }
        List<String> mode = param.getSupportedFocusModes();
        if(mode.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)){
            param.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
        }
        mCamera.setParameters(param);
    }

    @Override
    public boolean frame() {
        Log.e("CameraProvider" , "frame 1 "+mFrameSem.availablePermits()) ;
        try {
            mFrameSem.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.e("CameraProvider" , "frame 2 "+mFrameSem.availablePermits()) ;
        return false;
    }

    @Override
    public long getTimeStamp() {
        return -1;
    }

    @Override
    public boolean isLandscape() {
        return true;
    }

    @Override
    public void close() {
        mFrameSem.drainPermits();
        mFrameSem.release();

        mCamera.stopPreview();
        mCamera.release();
        mCamera=null;
    }
}
